package com.nulldev.util.concurrency.threadIt.v4.emapi.testing;

import com.nulldev.util.JVM.JVM;
import com.nulldev.util.VariableAPI.ArrayUtils;
import com.nulldev.util.concurrency.threadIt.v4.emapi.ExecutorManager;
import com.nulldev.util.concurrency.threadIt.v4.emapi.extensions.ExecutorFeatureExtensions;
import com.nulldev.util.concurrency.threadIt.v4.emapi.extensions.ExtendedExecutor;
import com.nulldev.util.concurrency.threadIt.v4.emapi.ft.FutureTask;
import com.nulldev.util.concurrency.threadIt.v4.executors.bqde.BQDE;
import com.nulldev.util.data.variable;

public class ExecutionLatencyTest {

	public static void main(String[] args) {
		ExecutorManager.get().setExecutor(new BQDE(16, 4, true));
		boolean supportsLPT = false;
		final Object exec = ExecutorManager.get().executor();
		JVM.println("Executor: " + exec);
		if (exec instanceof ExtendedExecutor) {
			ArrayUtils.printLln(((ExtendedExecutor) exec).supported());
			supportsLPT = ((ExtendedExecutor) exec).supportsFeature(ExecutorFeatureExtensions.EEX_executor_low_priority_threads)
					&& ((ExtendedExecutor) exec).supportsLPT() && ((ExtendedExecutor) exec).isLPTActive();
			JVM.println("supportsLPT: " + supportsLPT);
		}
		{
			final variable<Long> __ft_lat = new variable<Long>();
			final FutureTask<Object> o = new FutureTask<Object>() {

				@Override
				public Object execute() {
					final long inv = System.currentTimeMillis();
					JVM.println("Direct Latency: " + (inv - __ft_lat.get()) + " ms");
					return null;
				}
			};
			__ft_lat.set(System.currentTimeMillis());
			o.run();
		}
		{
			final variable<Long> __ft_lat = new variable<Long>();
			final FutureTask<Object> o = new FutureTask<Object>() {

				@Override
				public Object execute() {
					final long inv = System.currentTimeMillis();
					JVM.println("Executed Latency: " + (inv - __ft_lat.get()) + " ms");
					return null;
				}
			};
			__ft_lat.set(System.currentTimeMillis());
			ExecutorManager.get().queueTask(o);
		}
		if (supportsLPT) {
			final variable<Long> __ft_lat = new variable<Long>();
			final FutureTask<Object> o = new FutureTask<Object>() {

				@Override
				public Object execute() {
					final long inv = System.currentTimeMillis();
					JVM.println("(Low Priority) Executed Latency: " + (inv - __ft_lat.get()) + " ms");
					return null;
				}
			};
			__ft_lat.set(System.currentTimeMillis());
			ExecutorManager.get().queueTaskLP(o);
		}
		{
			final variable<Long> __ft_lat = new variable<Long>();
			final Runnable[] r = new Runnable[8];
			for (int i = 0; i < r.length; i++) {
				final int _i = i;
				r[_i] = new Runnable() {

					@Override
					public void run() {
						final long inv = System.currentTimeMillis();
						JVM.println("[" + _i + "] Batched Latency: " + (inv - __ft_lat.get()) + " ms");
					}
				};
			}
			__ft_lat.set(System.currentTimeMillis());
			ExecutorManager.get().asyncSubmitAll(r);
		}
	}
}
